﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XYZShell.Helper
{
	/// <summary>
	/// 通用相等比较
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <example><![CDATA[XYZShell.Helper.Equality<TResData>.CreateComparer( r => r.TaskID )]]></example>
	public static class Equality<T>
	{
		/// <summary>
		/// 根据委托获取相等比较
		/// </summary>
		/// <typeparam name="V"></typeparam>
		/// <param name="keySelector"></param>
		/// <returns></returns>
		public static IEqualityComparer<T> CreateComparer<V>( Func<T, V> keySelector )
		{
			return new CommonEqualityComparer<V>( keySelector );
		}
		/// <summary>
		/// 根据委托获取相等比较
		/// </summary>
		/// <typeparam name="V"></typeparam>
		/// <param name="keySelector"></param>
		/// <param name="comparer"></param>
		/// <returns></returns>
		public static IEqualityComparer<T> CreateComparer<V>( Func<T, V> keySelector, IEqualityComparer<V> comparer )
		{
			return new CommonEqualityComparer<V>( keySelector, comparer );
		}

		class CommonEqualityComparer<V> : IEqualityComparer<T>
		{
			private Func<T, V> keySelector;
			private IEqualityComparer<V> comparer;

			public CommonEqualityComparer( Func<T, V> keySelector, IEqualityComparer<V> comparer )
			{
				this.keySelector = keySelector;
				this.comparer = comparer;
			}
			public CommonEqualityComparer( Func<T, V> keySelector )
				: this( keySelector, EqualityComparer<V>.Default )
			{
			}

			public bool Equals( T x, T y )
			{
				return comparer.Equals( keySelector( x ), keySelector( y ) );
			}
			public int GetHashCode( T obj )
			{
				return comparer.GetHashCode( keySelector( obj ) );
			}
		}
	}

	public static class Comparison<T>
	{
		/// <summary>
		/// 根据函数委托获取比较接口
		/// </summary>
		/// <typeparam name="V"></typeparam>
		/// <param name="keySelector"></param>
		/// <returns></returns>
		public static IComparer<T> CreateComparer<V>( Func<T, V> keySelector )
		{
			return new CommonComparer<V>( keySelector );
		}
		/// <summary>
		/// 根据函数委托获取比较接口
		/// </summary>
		/// <typeparam name="V"></typeparam>
		/// <param name="keySelector"></param>
		/// <param name="comparer"></param>
		/// <returns></returns>
		public static IComparer<T> CreateComparer<V>( Func<T, V> keySelector, IComparer<V> comparer )
		{
			return new CommonComparer<V>( keySelector, comparer );
		}

		class CommonComparer<V> : IComparer<T>
		{
			private Func<T, V> keySelector;
			private IComparer<V> comparer;

			public CommonComparer( Func<T, V> keySelector, IComparer<V> comparer )
			{
				this.keySelector = keySelector;
				this.comparer = comparer;
			}
			public CommonComparer( Func<T, V> keySelector )
				: this( keySelector, Comparer<V>.Default )
			{
			}

			public int Compare( T x, T y )
			{
				return comparer.Compare( keySelector( x ), keySelector( y ) );
			}
		}
	}
}
